package com.springcloud.auth.authorization.oauth2;

import com.springcloud.auth.authorization.provider.SystemUserProvider;
import com.springcloud.common.core.entity.R;
import com.springcloud.common.core.exception.ApiException;
import com.springcloud.common.entity.SystemRole;
import com.springcloud.common.entity.SystemUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>  </p>
 *
 * @author mori
 * @since 10/31/2019 9:36 AM
 */
@Slf4j
@Service("userDetailsService")
public class SystemUserDetailsService implements UserDetailsService {

    private SystemUserProvider systemUserProvider;

    public SystemUserDetailsService(SystemUserProvider systemUserProvider) {
        this.systemUserProvider = systemUserProvider;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        R<SystemUser> userResponse = systemUserProvider.getSystemUserByUsername(username);
        if (!userResponse.ok()) {
            throw new ApiException(userResponse.getMsg());
        }
        SystemUser user = userResponse.getData();
        log.info("load user by username :{}", user.toString());

        return new User(
                user.getUserName(),
                user.getPassword(),
                true,
                true,
                true,
                true,
                this.obtainGrantedAuthorities(user));
    }

    private Set<GrantedAuthority> obtainGrantedAuthorities(SystemUser user) {
        R<Set<SystemRole>> roleResponse = systemUserProvider.getRoleListByUserId(user.getSystemUserId());
        if(!roleResponse.ok()){
            throw new ApiException(roleResponse.getMsg());
        }
        Set<SystemRole> roles = roleResponse.getData();
        log.info("user:{},roles:{}", user.getUserName(), roles);
        return roles.stream().map(role -> new SimpleGrantedAuthority(role.getRoleCode())).collect(Collectors.toSet());
    }

}
